import { Config, Inject, Provide } from '@midwayjs/decorator';
import { BaseService } from '@cool-midway/core';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { Repository } from 'typeorm';
import { CacheManager } from '@midwayjs/cache';
import * as jwt from 'jsonwebtoken';
// import { v1 as uuid } from 'uuid';
import { UserEntity } from '../entity/user';
import { WXService } from './wx';

/**
 * 登录
 */
@Provide()
export class LoginService extends BaseService {
    @Config('module.app.jwt')
    jwtConfig;

    @Inject()
    cacheManager: CacheManager;

    @Inject()
    wxService: WXService;

    @InjectEntityModel(UserEntity)
    userEntity: Repository<UserEntity>;


    /**
     * 登录
     * @param code 微信code
     */
    async login(code: string) {
        const { openid } = await this.wxService.getSessionKey(code);
        const user = await this.userEntity.findOneBy({ openid });
        if (!user) {
            const register = await this.userEntity.save({ nickname: '微信用户', avatar: 'https://oss-1257486725.cos.ap-guangzhou.myqcloud.com/app/xcxy/1583903764644099.jpg', openid });
            if (register) {
                const { expire, refreshExpire } = this.jwtConfig;
                const result = {
                    expire,
                    token: await this.generateToken(register, expire),
                    refreshExpire,
                    refreshToken: await this.generateToken(register, refreshExpire, true)
                };
                await this.cacheManager.set(`user:token:${register.id}`, result.token);
                return {
                    success: true,
                    message: '登录成功',
                    data: result
                };
            }
        } else {
            if (user.status === 0) {
                return {
                    success: false,
                    message: '账号已被禁用',
                    data: null
                };
            }
            const { expire, refreshExpire } = this.jwtConfig;
            const result = {
                expire,
                token: await this.generateToken(user, expire),
                refreshExpire,
                refreshToken: await this.generateToken(user, refreshExpire, true)
            };
            await this.cacheManager.set(`user:token:${user.id}`, result.token);
            return {
                success: true,
                message: '登录成功',
                data: result
            };
        }
    }

    /**
     * 生成Token
     * @param user 用户信息
     * @param expire 过期时间
     * @param isRefresh 是否刷新token
     */
    async generateToken(user, expire, isRefresh = false) {
        const tokenInfo = {
            isRefresh: false,
            userId: user.id,
            openid: user.openid
        }
        if (isRefresh) {
            tokenInfo.isRefresh = true;
        }
        return jwt.sign(tokenInfo, this.jwtConfig.secret, { expiresIn: expire });
    }

    /**
     * 刷新Token
     * @param refreshToken 刷新token
     */
    async refreshToken(refreshToken: string) {
        try {
            const decoded = jwt.verify(refreshToken, this.jwtConfig.secret);
            if (decoded && decoded['isRefresh']) {
                delete decoded['exp'];
                delete decoded['iat'];
                const { expire, refreshExpire } = this.jwtConfig;
                decoded['isRefresh'] = false;
                const result = {
                    expire,
                    token: jwt.sign(decoded, this.jwtConfig.secret, { expiresIn: expire }),
                    refreshExpire,
                    refreshToken: ''
                };
                decoded['isRefresh'] = true;
                result.refreshToken = jwt.sign(decoded, this.jwtConfig.secret, { expiresIn: refreshExpire });
                await this.cacheManager.set(`user:token:${decoded['userId']}`, result.token);
                return {
                    success: true,
                    message: 'Token刷新成功',
                    data: result
                };
            }
        } catch (err) {
            return {
                success: false,
                message: 'Token刷新失败',
                data: null
            };
        }
    }
}
